/**
 * \file queue.h
 * \brief Queue - FIFO em memória
 *
 * Estrutura de dados que segue a metedologia FIFO (First In First Out).
 */
# ifndef QUEUE_DEFINITION
# define QUEUE_DEFINITION

# include <stdlib.h>
# include "linked-list.h"

typedef struct {
	LinkedList *in;
	LinkedList *out;
	int elems;
} Queue; 

/**
 * \func Queue * newQueue()
 * \brief Cria uma nova Queue (aloca espaço em memória).
 * \return Nova Queue
 *
 * Esta função pode terminar obruptamente com o programa, se
 * não conseguir alocar espaço em memória. É por isso necessário garantir
 * que esta nunca atinja o limite.
 */
Queue * newQueue();
/**
 * \func int enqueue(Queue *queue, void *data)
 * \brief Coloca o elemento no pipe
 * \param queue Queue onde colocar o elemento
 * \param data Elemento (pode ser de qualquer tipo)
 * \return 1 se correu tudo bem, 0 pelo contrário
 *
 * Esta função pode terminar abruptamente, uma vez que faz uso
 * da função LinkedList * newElem() da estrutura linked-list.
 */
int enqueue (Queue *queue, void *data);
/**
 * \func void * dequeue(Queue *queue)
 * \brief Retira o elemento do fim do pipe.
 * \param queue O "pipe" Queue
 * \return O elemento ou NULL se não tiver elementos.
 */
void * dequeue (Queue *queue);
/**
 * \func void * peek(Queue *queue)
 * \brief Le o elemento que está na ponta de saida do pipe.
 * \param queue Queue de onde tirar o elemento.
 * \return O elemento ou NULL se a lista for vazia.
 */
void * peek (Queue *queue); // apenas olha para a que está para sair!

// Funções de transição entre tipos de dados
/**
 * \func LinkedList * queueToLinkedList (Queue *q)
 * \brief Passa de queue para linked-list
 * \param q Queue a transformar
 * \return LinkedLista ligada ou NULL senão conseguir
 */
LinkedList * queueToLinkedList (Queue *q);
/**
 * \func Queue * linkedLinkedListToQueue (List *lst)
 * \brief Passa de linked-list para Queue
 * \param lst LinkedLista a transformar
 * \return A queue ou NULL se não conseguir.
 */
Queue * linkedLinkedListToQueue (LinkedList *lst);

/**
 * \brief Liberta da memória a estrutura
 * \param q queue
 */
void freeQueue (Queue *q);

# endif
